package expression

import (
	"cdam/qiniu/qlang/spec"
	"fmt"
	"github.com/pkg/errors"
	"reflect"
	"strings"
)

type OutData struct {
	Result interface{} // 数据结果
}

func (d OutData) Bool() (bool, error) {
	if d.IsUndefined() {
		return false, errors.Errorf("未定义变量: spec.Undefined")
	}
	if d.IsNil() {
		return false, nil
	}
	return result2bool(d.Result)
}

func result2bool(result interface{}) (bool, error) {
	switch result.(type) {
	case bool:
		return result.(bool), nil
	case int, int8, int16, int32, int64, uint, uint16, uint32, uint64:
		return result.(int) != 0, nil
	case float32, float64:
		return result.(float64) != 0, nil
	case string:
		r := strings.ToLower(result.(string))
		return result.(string) != "" && r != "false" && r != "off", nil
	case uint8:
		return result.(uint8) != 0, nil
	default:
		v := reflect.ValueOf(result)
		switch v.Kind() {
		case reflect.Slice, reflect.Map:
			return v.Len() > 0, nil
		default:
			if !v.IsValid() {
				return false, nil
			}
			if v.IsNil() {
				return false, nil
			}
			return false, fmt.Errorf("不能处理的类型:%s", v)
		}
	}
}

func (d *OutData) IsUndefined() bool {
	return d != nil && d.Result == spec.Undefined
}

func (d *OutData) IsNil() bool {
	return d == nil || d.Result == nil
}

func (d *OutData) SliceStr() ([]string, error) {
	if d.IsUndefined() {
		return nil, errors.Errorf("未定义变量：spec.Undefined")
	}
	if d.IsNil() {
		return nil, nil
	}
	r, ok := d.Result.([]string)
	if ok {
		return r, nil
	}
	return nil, errors.Errorf("返回值的类型错误:%s", r)
}
